package mybox.junit;

import java.awt.Point;
import java.awt.Polygon;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import at.innoc.util.obstacles.AAAPolygon;
import at.innoc.util.obstacles.DPoint;
import at.innoc.util.obstacles.exceptions.NotEndpointOfLineException;
import at.innoc.util.obstacles.exceptions.ParallelException;


import junit.framework.TestCase;

import mybox.engine.Circle;
import mybox.engine.File4Qcad;
import mybox.engine.Line;
import mybox.engine.QVector;
import mybox.engine.ReferenceIOutput;

import static java.lang.Math.*;

//import at.innoc.util.obstacles.AAAPolygon;


public class Polygon2QCAD_TC extends TestCase{
	
public void test_Polygon2QCAD() throws SecurityException, IOException  {
		
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());		
		
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();
	Polygon polygon1 = new Polygon();
	polygon1.addPoint(10,20);
	polygon1.addPoint(30,40);
	polygon1.addPoint(50,10);

	Polygon polygon2 = new Polygon();
	polygon2.addPoint(0,20);
	polygon2.addPoint(10,40);
	polygon2.addPoint(-10,30);
	polygon2.addPoint(-20,40);
	polygon2.addPoint(-30,30);

	Polygon polygon3 = new Polygon();
	polygon3.addPoint(4,15);
	polygon3.addPoint(-20,10);
	polygon3.addPoint(-10,-10);

	Polygon polygon4 = new Polygon();
	polygon4.addPoint(30,-10);
	polygon4.addPoint(60,10);
	polygon4.addPoint(60,2);
	
	Polygon polygon5 = new Polygon();
	polygon5.addPoint(-5,-30);
	polygon5.addPoint(5,-30);
	polygon5.addPoint(0,-40);

	polygonList.add(polygon1);
	polygonList.add(polygon2);
	polygonList.add(polygon3);
	polygonList.add(polygon4);
	polygonList.add(polygon5);
	
	
	for (Polygon polygon:polygonList) { 
		System.out.println("polygon added to qcad");
		for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
			QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
			QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
			Line line = new Line(file4qcad, begin, end);
			line.draw();
		}
	}
		
	
	file4qcad.close();
	
}

public void test_Polygon2QCAD2() throws SecurityException, IOException  {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();

	Polygon polygon1 = new Polygon();
	polygon1.addPoint(10,-10);
	polygon1.addPoint(20,0);
	polygon1.addPoint(10,10);	
	
	
	polygonList.add(polygon1);


	for (Polygon polygon:polygonList) { 
		System.out.println("polygon:");
		for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
			QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
			QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
			Line line = new Line(file4qcad, begin, end);
			line.draw();
		}
	}

	file4qcad.close();

}

public void test_FahrzeugPolygon2QCAD2() throws SecurityException, IOException  {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();

	Polygon tP=null;
	
	tP=new Polygon();tP.addPoint(0,0);tP.addPoint(10000,0);polygonList.add(tP);
	tP=new Polygon();tP.addPoint(1000,0);tP.addPoint(10983,568);polygonList.add(tP);

	for (Polygon polygon:polygonList) { 
		System.out.println("polygon:");
		for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
			QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
			QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
			Line line = new Line(file4qcad, begin, end);
			line.draw();
		}
	}

	file4qcad.close();

}

public void test_PolgygonTest_test_closestPoints() throws SecurityException, IOException  {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();

	Polygon polygon1 = new Polygon();
	polygon1.addPoint(5,1);
	polygon1.addPoint(5,2);
	polygon1.addPoint(6,3);
	polygon1.addPoint(5,4);
	polygon1.addPoint(3,3);
	polygonList.add(polygon1);

	Polygon polygon2 = new Polygon();
	polygon2.addPoint(3,2);
	polygon2.addPoint(2,3);
	polygon2.addPoint(2,4);
	polygon2.addPoint(1,4);
	polygon2.addPoint(0,3);
	polygonList.add(polygon2);

	Polygon polygon3 = new Polygon();
	polygon3.addPoint(1,5);
	polygon3.addPoint(1,6);
	polygon3.addPoint(-1,3);		
	polygonList.add(polygon3);

	Polygon polygon4 = new Polygon();
	polygon4.addPoint(9,-1);
	polygon4.addPoint(11,-1);
	polygon4.addPoint(9,1);		
	polygonList.add(polygon4);
	
	


	for (Polygon polygon:polygonList) { 
		System.out.println("polygon:");
		for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
			QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
			QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
			Line line = new Line(file4qcad, begin, end);
			line.draw();
		}
	}

	file4qcad.close();

}

public void test_LuebeckTests_sectorMinDistance14Lbk() throws SecurityException, IOException {
	
File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();

	Polygon polygon1 = new Polygon();
	polygon1.addPoint(741,78);
	polygon1.addPoint(745,237);
	polygon1.addPoint(762,257);
	polygon1.addPoint(778,311);
	polygon1.addPoint(686,365);
	polygon1.addPoint(646,379);
	polygon1.addPoint(522,442);
	polygon1.addPoint(496,495);
	polygon1.addPoint(415,536);
	polygon1.addPoint(337,485);
	polygon1.addPoint(192,477);
	polygon1.addPoint(139,507);
	polygon1.addPoint(90,489);
	polygon1.addPoint(69,503);
	polygon1.addPoint(43,489);
	polygon1.addPoint(39,466);
	polygon1.addPoint(39,466);
	polygon1.addPoint(127,332);
	polygon1.addPoint(313,302);
	polygon1.addPoint(330,294);
	polygon1.addPoint(438,202);
	polygon1.addPoint(483,147);
	polygon1.addPoint(524,85);
	polygon1.addPoint(541,45);
	polygon1.addPoint(1,1);
	polygon1.addPoint(0,572);
	polygon1.addPoint(882,572);
	polygon1.addPoint(882,0);
	polygon1.addPoint(741,78);	
	
	polygonList.add(polygon1);
	
	


	for (Polygon polygon:polygonList) { 
		System.out.println("polygon:");
		for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
			QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
			QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
			Line line = new Line(file4qcad, begin, end);
			line.draw();
		}
	}

	file4qcad.close();
	
}

public void test_LuebeckTests_sectorMinDistance15Lbk() throws SecurityException, IOException {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
		
		ArrayList<Polygon> polygonList = new ArrayList<Polygon>();

		Polygon polygon1 = new Polygon();
		polygon1.addPoint(741,78);
		polygon1.addPoint(745,237);
		polygon1.addPoint(762,257);
		polygon1.addPoint(778,311);
		polygon1.addPoint(686,365);
		polygon1.addPoint(646,379);
		polygon1.addPoint(522,442);
		polygon1.addPoint(496,495);
		polygon1.addPoint(415,536);
		polygon1.addPoint(337,485);
		polygon1.addPoint(192,477);
		polygon1.addPoint(139,507);
		polygon1.addPoint(90,489);
		polygon1.addPoint(69,503);
		polygon1.addPoint(43,489);
		polygon1.addPoint(39,466);
		polygon1.addPoint(39,466);
		polygon1.addPoint(127,332);
		polygon1.addPoint(313,302);
		polygon1.addPoint(330,294);
		polygon1.addPoint(438,202);
		polygon1.addPoint(483,147);
		polygon1.addPoint(524,85);
		polygon1.addPoint(541,45);
		polygon1.addPoint(1,1);
		polygon1.addPoint(0,572);
		polygon1.addPoint(882,572);
		polygon1.addPoint(882,0);
		polygon1.addPoint(741,78);	
		
		polygonList.add(polygon1);
		
		


		for (Polygon polygon:polygonList) { 
			System.out.println("polygon:");
			for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
				QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
				QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
				Line line = new Line(file4qcad, begin, end);
				line.draw();
			}
		}
		
		/*
		assertEquals(java.lang.Math.abs(sectorMinVal[0] -189.2957),		0,0.0001);		
		assertEquals(java.lang.Math.abs(sectorMinVal[12] -198.4188),	0,0.0001);
		assertEquals(java.lang.Math.abs(sectorMinVal[22] -268.4946),	0,0.0001);		
		assertEquals(java.lang.Math.abs(sectorMinVal[41] -71.0066),		0,0.0001);
		assertEquals(java.lang.Math.abs(sectorMinVal[91] -23.7578),
		*/		
		//print array
		Point pov = new Point(500,400); 
		for (int phiInt=0; phiInt<180;phiInt++) {
			if (	phiInt==0 || phiInt==1
				||	phiInt==12 || phiInt==13
				||	phiInt==22 || phiInt==23
				||	phiInt==41 || phiInt==42
				||	phiInt==91 || phiInt==92
				||	phiInt==100 || phiInt==101
					) {
			double realPhi=(phiInt+45)*2*java.lang.Math.PI/180;
			double r=1000;
			QVector begin = new QVector(pov.x,pov.y);
			QVector end = new QVector(pov.x+r*cos(realPhi),pov.y+r*sin(realPhi));
			Line qline = new Line(file4qcad,begin, end);
			qline.draw();
			}
		}

		file4qcad.close();
		
	}

public ArrayList<Polygon> createRobotfahrzeugData() {
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();
	
	
	return polygonList;
}

public ArrayList<Polygon> createEckerfoerdeData() {
	
	ArrayList<Polygon> polygonList = new ArrayList<Polygon>();
	Polygon polygon1 = new Polygon();
	
	polygon1.addPoint(-8474,-61201);
	polygon1.addPoint(-4969,-59737);
	polygon1.addPoint(1007,-58220);
	polygon1.addPoint(8366,-56994);
	polygon1.addPoint(13063,-60486);
	polygon1.addPoint(23488,-62454);
	polygon1.addPoint(43152,-31689);
	polygon1.addPoint(36494,-17859);
	polygon1.addPoint(27037,-21539);
	polygon1.addPoint(14777,-9501);
	polygon1.addPoint(1693,12312);
	polygon1.addPoint(-1865,14651);
	polygon1.addPoint(-1255,22243);
	polygon1.addPoint(-2402,23971);
	polygon1.addPoint(-4905,24006);
	polygon1.addPoint(-8701,27816);
	polygon1.addPoint(-8625,28400);
	polygon1.addPoint(-7188,32946);
	polygon1.addPoint(-12869,32481);
	polygon1.addPoint(-14010,29146);
	polygon1.addPoint(-15202,27441);
	polygon1.addPoint(-17748,27194);
	polygon1.addPoint(-19125,21685);
	polygon1.addPoint(-23448,18937);
	polygon1.addPoint(-25473,20889);
	polygon1.addPoint(-29526,17992);
	polygon1.addPoint(-22902,6503);
	polygon1.addPoint(-18906,9285);
	polygon1.addPoint(-15365,9879);
	polygon1.addPoint(-8920,5280);
	polygon1.addPoint(-6213,2372);
	polygon1.addPoint(-3885,2321);
	polygon1.addPoint(-695,-330);
	polygon1.addPoint(3064,-7333);
	polygon1.addPoint(5153,-14289);
	polygon1.addPoint(-2008,-17341);
	polygon1.addPoint(-328,-30384);
	polygon1.addPoint(2907,-34113);
	polygon1.addPoint(2477,-50209);
	polygon1.addPoint(-933,-54761);
	polygon1.addPoint(-8207,-58967);
	polygon1.addPoint(-10008,-58872);
	polygon1.addPoint(-8474,-61201);	
   
	polygonList.add(polygon1);
	
	Polygon polygon2 = new Polygon();
	
	polygon2.addPoint(4783,-44663);
	polygon2.addPoint(7547,-44663);
	polygon2.addPoint(7547,-39103);
	polygon2.addPoint(4783,-39103);
	polygon2.addPoint(4783,-44663);
	
	polygonList.add(polygon2);
	
	return polygonList;
	
}

public void drawPovAndRef(File4Qcad file4qcad, QVector refPoint, QVector pov) {
	
	Circle refCircle = new Circle(file4qcad, refPoint,100);
	refCircle.draw();
	
	Circle currPov = new Circle(file4qcad, pov,200);
	currPov.draw();
	
}

public void drawPolygonData(ArrayList<Polygon> polygonList, File4Qcad file4qcad) {
	
	for (Polygon polygon:polygonList) { 
		System.out.println("polygon:");
		for (int lineIdx=0;lineIdx<polygon.npoints;lineIdx++) {
			QVector begin = new QVector(polygon.xpoints[lineIdx], polygon.ypoints[lineIdx]);
			QVector end = new QVector(polygon.xpoints[(lineIdx+1)%polygon.npoints],polygon.ypoints[(lineIdx+1)%polygon.npoints]);
			Line line = new Line(file4qcad, begin, end);
			line.draw();
		}
	}
	
}

public void test_EckernfoerdeData_biggerCut() throws SecurityException, IOException, NotEndpointOfLineException, ParallelException {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
	ArrayList<Polygon> polygonList = createEckerfoerdeData();
	
	
	//drawPolygonData(polygonList,file4qcad);
	
	                                        Point pov = new Point(8382,-39024);
	drawPovAndRef(file4qcad, new QVector(-3435,2516), new QVector(8382,-39024));
		
    ArrayList<DPoint> innerLine = AAAPolygon.closestPointsPolygon(polygonList, pov, AAAPolygon.DEBUGINFO_OFF);
	
    
	for (	  int pointIdx=0	
			; pointIdx<innerLine.size()-1;
			  pointIdx++) {		
		QVector begin = new QVector(innerLine.get(pointIdx).x, innerLine.get(pointIdx).y);
		QVector end = new QVector(innerLine.get(pointIdx+1).x, innerLine.get(pointIdx+1).y);
		Line line = new Line(file4qcad, begin, end);
		line.draw();
	}
    
	
	file4qcad.close();
	
}


public void test_EckernfoerdeData_NaN() throws SecurityException, IOException, NotEndpointOfLineException, ParallelException {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
    ArrayList<Polygon> polygonList = createEckerfoerdeData();
	
	
	//drawPolygonData(polygonList,file4qcad);
	
    
    										Point pov = new Point(8324,-39044);
    drawPovAndRef(file4qcad, new QVector(-3435,2516), new QVector(8324,-39044));

    ArrayList<DPoint> innerLine = AAAPolygon.closestPointsPolygon(polygonList, pov, AAAPolygon.DEBUGINFO_OFF);	
    
	for (int pointIdx=0			
			;pointIdx<innerLine.size()-1;
			pointIdx++) {
		QVector begin = new QVector(innerLine.get(pointIdx).x, innerLine.get(pointIdx).y);
		QVector end = new QVector(innerLine.get(pointIdx+1).x, innerLine.get(pointIdx+1).y);
		Line line = new Line(file4qcad, begin, end);
		line.draw();
	}
	
	file4qcad.close();
	
}

public void test_EckernfoerdeData_neuerFall() throws SecurityException, IOException, NotEndpointOfLineException, ParallelException {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
    ArrayList<Polygon> polygonList = createEckerfoerdeData();
	
	
	//drawPolygonData(polygonList,file4qcad);
	
    
    										Point pov = new Point(6752,-45020);
    drawPovAndRef(file4qcad, new QVector(-3435,2516), new QVector(6752,-45020));

    ArrayList<DPoint> innerLine = AAAPolygon.closestPointsPolygon(polygonList, pov, AAAPolygon.DEBUGINFO_OFF);	
    
	for (int pointIdx=0			
			;pointIdx<innerLine.size()-1;
			pointIdx++) {
		QVector begin = new QVector(innerLine.get(pointIdx).x, innerLine.get(pointIdx).y);
		QVector end = new QVector(innerLine.get(pointIdx+1).x, innerLine.get(pointIdx+1).y);
		Line line = new Line(file4qcad, begin, end);
		line.draw();
	}
	
	file4qcad.close();
	
}

public void test_EckernfoerdeData_kleineEinkerbung() throws SecurityException, IOException, NotEndpointOfLineException, ParallelException {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
    ArrayList<Polygon> polygonList = createEckerfoerdeData();
	
	
	//drawPolygonData(polygonList,file4qcad);
	
	Circle povCircle = new Circle(file4qcad, new QVector(-3435,2516),100);
	povCircle.draw();
	
	Point pov = new Point(-3435,2516);
	
    ArrayList<DPoint> innerLine = AAAPolygon.closestPointsPolygon(polygonList, pov, AAAPolygon.DEBUGINFO_OFF);
	
    
	for (int pointIdx=0			
			;pointIdx<innerLine.size()-1;
			pointIdx++) {		
		QVector begin = new QVector(innerLine.get(pointIdx).x, innerLine.get(pointIdx).y);
		QVector end = new QVector(innerLine.get(pointIdx+1).x, innerLine.get(pointIdx+1).y);
		Line line = new Line(file4qcad, begin, end);
		line.draw();
	}
    
	
	file4qcad.close();
	
}



public void test_Array2PolarDiag() throws SecurityException, IOException {
	
	File4Qcad file4qcad = new File4Qcad(ReferenceIOutput.testoutputFile());
	
	BufferedReader inBuffer = new BufferedReader(new FileReader(ReferenceIOutput.testInputFile()));
	String line;
	StringBuilder arrayBuff = new StringBuilder();
	while ((line = inBuffer.readLine()) != null) {
		arrayBuff.append(line);		
	}
	inBuffer.close();
	String[] polArr = arrayBuff.toString().split("\\,");
	
	
	int rotation=0;
	int[] polArrInt = new int[polArr.length-1];
	for (int index=0; index<polArr.length; index++) {
		if (index<1) rotation=Integer.parseInt(polArr[index]);
	    else polArrInt[index-1]=(int)Double.parseDouble(polArr[index].trim());
	}	
	
	//Windcorrection
	int arrSize=polArrInt.length;	
	int[] sectorRotatedVal = new int[arrSize];	
	
	for (int sectorIdx=0;sectorIdx<polArrInt.length;sectorIdx++) {			  
	      sectorRotatedVal[(sectorIdx+rotation+arrSize)%arrSize]=polArrInt[sectorIdx];
	}
	
	
	int minimum=100000,maximum=-100000;		
	for (int num : polArrInt) {
		if (num<minimum) minimum=num;
		if (num>maximum) maximum=num;
	}
	int elevation=0;
	if (minimum<0) elevation=-minimum+1;
	System.out.println("min="+minimum+" max="+maximum);
	
	Polygon polygon1 = new Polygon();
	
	for (int phiInt=0; phiInt<polArrInt.length;phiInt++) {
		double realPhi=phiInt*2*java.lang.Math.PI/polArrInt.length;
		double r=sectorRotatedVal[phiInt]+elevation;
		polygon1.addPoint((int)(1000*r*java.lang.Math.cos(realPhi)), (int) (1000*r*java.lang.Math.sin(realPhi)));		
	}
	
	
	
	for (int lineIdx=0;lineIdx<polygon1.npoints;lineIdx++) {
		QVector begin = new QVector(polygon1.xpoints[lineIdx], polygon1.ypoints[lineIdx]);
		QVector end = new QVector(polygon1.xpoints[(lineIdx+1)%polygon1.npoints],polygon1.ypoints[(lineIdx+1)%polygon1.npoints]);
		Line qline = new Line(file4qcad, begin, end);
		qline.draw();
	}
	
    
	
	
	file4qcad.close();
	
	
}

}
